#include "FmodAudio.h"
#include "Tetrisstd.h"

Sample::Sample()
{
    sample = NULL;
    channel = NULL;
}
    
Sample::~Sample()
{
    if (sample != NULL) {
		sample->release();
        sample = NULL;
    }
}

Audio::Audio()
{
    system = NULL;
}
    
Audio::~Audio()
{
    //release all samples
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
		delete *i; 
        (*i) = NULL;
    }
        
	if(system)
		system->release();
}
    
bool Audio::Init()
{
    if (FMOD::System_Create(&system) != FMOD_OK) {
        return false;
    }
    
	if(system->init(100, FMOD_INIT_NORMAL, NULL) != FMOD_OK){
        return false;
    }
    
    return true;
}
    
void Audio::Update()
{
	system->update();
}
    
    
Sample* Audio::Load(std::string filename)
{
    if (filename.length() == 0) return false;
        
    Sample *sample = new Sample();
    
    try {
        FMOD_RESULT res;
		res = system->createSound(filename.c_str(), FMOD_DEFAULT, NULL, &sample->sample);

        if (res != FMOD_OK) {
            sample = NULL;
        }
    } catch (...) {
        sample = NULL;
    }
            
    return sample;
}

Sample* Audio::LoadStream(std::string filename)
{
	if (filename.length() == 0) return false;
        
    Sample *sample = new Sample();
    
    try {
        FMOD_RESULT res;
		res = system->createStream(filename.c_str(), FMOD_DEFAULT, NULL, &sample->sample);

        if (res != FMOD_OK) {
            sample = NULL;
        }
    } catch (...) {
        sample = NULL;
    }
            
    return sample;
}
    
bool Audio::Load(std::string filename, std::string name)
{
    if (filename.length() == 0 || name.length() == 0) return false;
        
    Sample *sample = new Sample();
    sample->setName(name);
    
    FMOD_RESULT res;
	res = system->createSound(filename.c_str(), FMOD_DEFAULT, NULL, &sample->sample);

    if (res != FMOD_OK) {
        return false;
    }
    samples.push_back(sample);
    
    return true;    
}
    
bool Audio::SampleExists(std::string name)
{
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        if ((*i)->getName() == name)
        {
            return true;
        }         
    }
    
    return false;
}
    
bool Audio::IsPlaying(std::string name)
{
    Sample *samp = FindSample(name);
    if (samp == NULL) return false;
        
    int index;
	samp->channel->getIndex(&index);
        
    // FMOD returns 99 if sample is playing, 0 if not
    return (index > 0);
        
}
        
Sample *Audio::FindSample(std::string name)
{
    Sample *sample = NULL;
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        if ((*i)->getName() == name)
        {
            sample = (*i);
            break;
        }
    }
    return sample;
}
    
    
bool Audio::Play(std::string name)
{
    FMOD_RESULT res;
    Sample *sample = FindSample(name);
    
    if (sample->sample != NULL) {
        try {
            //sample found, play it
			res = system->playSound(FMOD_CHANNEL_FREE, sample->sample, true, &sample->channel);

            if (res!= FMOD_OK) return false;
                
			sample->channel->setLoopCount(-1);
			sample->channel->setPaused(false);
                
        } catch (...) {
            return false;
        }
    }
    
    return true;
}
    
bool Audio::Play(Sample *sample)
{
    FMOD_RESULT res;
    if (sample == NULL) return false;
    if (sample->sample == NULL) return false;
    
    res = system->playSound(FMOD_CHANNEL_FREE, sample->sample, true, &sample->channel);

    if (res!= FMOD_OK) return false;

    sample->channel->setLoopCount(-1);
	sample->channel->setPaused(false);
    
    return true;
}
    
void Audio::Stop(std::string name)
{
    if (!IsPlaying(name)) return;
    
    Sample *sample = FindSample(name);
    if (sample == NULL) return;
        
	sample->channel->stop();
}
    
void Audio::StopAll()
{
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        (*i)->channel->stop();
    }
}
    
void Audio::StopAllExcept(std::string name)
{
    for (Iterator i = samples.begin(); i != samples.end(); ++i)
    {
        if ((*i)->getName() != name)
        {
            (*i)->channel->stop();
        }
    }
}


